home *** CD-ROM | disk | FTP | other *** search
/ Apple WWDC 1996 / WWDC96_1996 (CD).toast / Technology Materials / QuickTime VR / Windows / Samples / QD3DSample / 3DShell.c next >
Encoding:
C/C++ Source or Header  |  1996-05-01  |  21.9 KB  |  658 lines  |  [TEXT/LMAN]

  1. #include <windows.h>        // required for all Windows applications
  2. #include "resource.h"        // Windows resource IDs
  3. #include "3dshell.h"        // specific to this program
  4. #include <stdio.h>
  5.  
  6. #include "Box3DSupport.h"
  7.  
  8. HINSTANCE hInst;              // current instance
  9.  
  10. DocumentPtr        gDocument;
  11.  
  12. char szAppName[] = "QuickDraw 3D Demo";        // The name of this application
  13. char szTitle[]   = "QuickDraw 3D Demo";        // The title bar text
  14.  
  15. void        OpenModelFile(void);
  16. void        SaveModelFile(void);
  17.  
  18. TQ3Status    BrowseForPathName(char *inPathName, BOOLEAN fOpen);
  19.  
  20. void        UpdateFrame(void);
  21.  
  22. void        InitDocumentData( DocumentPtr theDocument, HWND inWindow );
  23. void        DisposeDocumentData( DocumentPtr theDocument);
  24. TQ3Status    DocumentDraw3DData( DocumentPtr theDocument );
  25.  
  26. TQ3Status    DocumentNewWindowSize(DocumentPtr theDocument, unsigned long width, unsigned long height);
  27.  
  28. TQ3Status    PaintDocumentWindow(DocumentPtr theDocument);
  29.  
  30. TQ3Status    GetToolBarPosition(DocumentPtr theDocument, unsigned long *x, unsigned long *y);
  31. TQ3Status    GetToolBarSize(DocumentPtr theDocument, unsigned long *width, unsigned long *height);
  32. static void MyErrorHandler(TQ3Error firstError, TQ3Error lastError, long refCon); 
  33. #define REFERROR 00L
  34. #define REFWARNING 01L
  35. #define REFNOTICE 02L
  36.  
  37. static void StartTimer( void );
  38. static void StopTimer( void );
  39.  
  40. VOID CALLBACK TimerProc( HWND, UINT, UINT, DWORD );    
  41. UINT gTimer;
  42.  
  43.  
  44. int CALLBACK WinMain(
  45.         HINSTANCE hInstance,
  46.         HINSTANCE hPrevInstance,
  47.         LPSTR lpCmdLine,
  48.         int nCmdShow)
  49. {
  50.         MSG msg;
  51.         HANDLE hAccelTable;
  52.  
  53.         if (!InitApplication(hInstance)) 
  54.         {
  55.             return (FALSE);    
  56.         }
  57.  
  58.         if (!InitInstance(hInstance, nCmdShow)) 
  59.         {
  60.             return (FALSE);
  61.         }
  62.  
  63.         hAccelTable = LoadAccelerators (hInstance, MAKEINTRESOURCE(IDR_GENERIC));
  64.  
  65.         StartTimer();
  66.         while (GetMessage(&msg, NULL, 0, 0)) {
  67.             if (!TranslateAccelerator (msg.hwnd, hAccelTable, &msg)) {
  68.                 TranslateMessage(&msg);
  69.                 DispatchMessage(&msg);
  70.             }
  71.         }
  72.         StopTimer();
  73.  
  74.         return (msg.wParam); // Returns the value from PostQuitMessage
  75. }
  76.  
  77. void UpdateFrame(void)
  78. {
  79.     TQ3Matrix4x4    tmp;
  80.     RECT            aWinRect;
  81.     BOOL            aResult;
  82.  
  83.     Q3Matrix4x4_SetRotate_XYZ(&tmp, 0.05F, 0.05F, 0.05F);
  84.     Q3Matrix4x4_Multiply(&gDocument->fRotation, &tmp, &gDocument->fRotation);
  85.     aResult = GetClientRect(gDocument->fWindow, (LPRECT)&aWinRect);
  86.     aWinRect.bottom = aWinRect.top + gDocument->fHeight;
  87.     aResult = InvalidateRect(gDocument->fWindow, &aWinRect, FALSE);    
  88. }
  89.  
  90.  
  91. BOOL InitApplication(HINSTANCE hInstance)
  92. {
  93.         WNDCLASS  wc;
  94.  
  95.         wc.style         = CS_HREDRAW | CS_VREDRAW;
  96.         wc.lpfnWndProc   = (WNDPROC)WndProc;       
  97.         wc.cbClsExtra    = 0;                      
  98.         wc.cbWndExtra    = 0;                     
  99.         wc.hInstance     = hInstance;             
  100.         wc.hIcon         = LoadIcon (hInstance, MAKEINTRESOURCE(IDI_APP)); 
  101.         wc.hCursor       = LoadCursor(NULL, IDC_ARROW);
  102.         wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
  103.         wc.lpszMenuName  = MAKEINTRESOURCE(IDR_GENERIC); 
  104.         wc.lpszClassName = szAppName;              
  105.  
  106.         return (RegisterClass(&wc));
  107. }
  108.  
  109. BOOL InitInstance(
  110.         HINSTANCE       hInstance,
  111.         int             nCmdShow)
  112. {
  113.         HWND            hWnd; 
  114.  
  115.         hInst = hInstance; 
  116.         hWnd = CreateWindowEx(
  117.                 WS_EX_WINDOWEDGE | WS_EX_CLIENTEDGE,
  118.                 szAppName,          
  119.                 szTitle,             
  120.                 WS_OVERLAPPED|WS_CAPTION|WS_SYSMENU, 
  121.                 25, 25, 400, 450,      // fixed size windows
  122.                 NULL,                
  123.                 NULL,                
  124.                 hInstance,           
  125.                 NULL                 
  126.         );
  127.  
  128.         if (!hWnd) 
  129.         {
  130.             return (FALSE);
  131.         }
  132.  
  133.  
  134.         ShowWindow(hWnd, nCmdShow); 
  135.         UpdateWindow(hWnd);        
  136.  
  137.         return (TRUE);             
  138.  
  139. }
  140.  
  141. static void StartTimer( void )
  142. {
  143.     gTimer = SetTimer( NULL, 0, 100, (TIMERPROC) TimerProc );
  144. }
  145.  
  146. static void StopTimer( void )
  147. {
  148.     KillTimer( NULL, gTimer );
  149. }
  150.  
  151. VOID CALLBACK TimerProc(
  152.     HWND hwnd,    // handle of window for timer messages 
  153.     UINT uMsg,    // WM_TIMER message
  154.     UINT idEvent,    // timer identifier
  155.     DWORD dwTime     // current system time
  156.    )    
  157. {
  158.     UpdateFrame();
  159. }
  160.  
  161.  
  162. LRESULT CALLBACK WndProc(
  163.                 HWND hWnd,        
  164.                 UINT message,      
  165.                 WPARAM uParam,     
  166.                 LPARAM lParam)   
  167. {
  168.         int wmId, wmEvent;
  169.         TQ3Status    aStatus;
  170.         PAINTSTRUCT PaintStruct;
  171.  
  172.         switch (message) 
  173.         {
  174.             case WM_COMMAND:
  175.  
  176.                 wmId    = LOWORD(uParam);
  177.                 wmEvent = HIWORD(uParam);
  178.  
  179.                 switch (wmId) 
  180.                 {
  181.                     case IDM_ABOUT:
  182.                         StopTimer();
  183.                         DialogBox(hInst,          
  184.                                 MAKEINTRESOURCE(IDD_ABOUTBOX),
  185.                                 hWnd,                 
  186.                                 (DLGPROC)About);
  187.                         StartTimer();
  188.                         break;
  189.                     case IDM_OPEN:
  190.                         StopTimer();
  191.                         OpenModelFile();
  192.                         StartTimer();
  193.                         break;
  194.                     case IDM_SAVEAS:
  195.                         StopTimer();
  196.                         SaveModelFile();
  197.                         StartTimer();
  198.                         break;
  199.  
  200.                     case IDM_EXIT:
  201.                         DestroyWindow (hWnd);
  202.                         break;
  203.  
  204.                     default:
  205.                         return (DefWindowProc(hWnd, message, uParam, lParam));
  206.                 }
  207.                 break;
  208.  
  209.             case WM_CREATE:
  210.                 aStatus = Q3Initialize();
  211.                 Q3Error_Register( MyErrorHandler, REFERROR );
  212.                 Q3Warning_Register( MyErrorHandler, REFWARNING );
  213.                 Q3Notice_Register( MyErrorHandler, REFNOTICE );
  214.                 gDocument = (DocumentPtr)malloc(sizeof(DocumentRec));
  215.                 InitDocumentData(gDocument, hWnd);
  216.                 break;
  217.  
  218.             case WM_DESTROY:  // message: window being destroyed
  219.                 PostQuitMessage(0);
  220.                 DisposeDocumentData(gDocument);
  221.                 free(gDocument);
  222.                 aStatus = Q3Exit();
  223.                 break;
  224.  
  225.             case WM_PAINT:
  226.                 BeginPaint(gDocument->fWindow, &PaintStruct);                
  227.                 DocumentDraw3DData(gDocument);
  228.                 EndPaint(gDocument->fWindow, &PaintStruct);
  229.                 break;
  230.  
  231.             default:          // Passes it on if unproccessed
  232.                     return (DefWindowProc(hWnd, message, uParam, lParam));
  233.         }
  234.         return (0);
  235. }
  236.  
  237. static void MyErrorHandler(TQ3Error firstError, TQ3Error lastError, long refCon) 
  238.     char buf[512];
  239.     switch( refCon )
  240.     {
  241.         case REFERROR:
  242.             sprintf(buf, "QD3D ERROR %d\n", lastError); 
  243.             break;
  244.         case REFWARNING:
  245.             sprintf(buf, "QD3D WARNING %d\n", lastError); 
  246.             break;
  247.         case REFNOTICE:
  248.             sprintf(buf, "QD3D NOTICE %d\n", lastError); 
  249.             break;
  250.     }
  251.     OutputDebugString(buf); 
  252. }
  253.  
  254. char ExtFilter[] = "QuickDraw 3D Metafiles\0*.3dmf;*.3dm;*.q3d;*.qd3d\0All Files\0*.*\0\0";
  255.  
  256. // put up common dialog; fOpen == TRUE for Open, FALSE for Save As.
  257. TQ3Status    BrowseForPathName(char *inPathName, BOOLEAN fOpen) 
  258. {
  259.     OPENFILENAME aFileName;
  260.     TQ3Status     aStatus = kQ3Success;
  261.  
  262.     inPathName[0] = 0;
  263.     aFileName.lStructSize = sizeof(OPENFILENAME);
  264.     aFileName.hwndOwner = gDocument->fWindow;
  265.     aFileName.hInstance = NULL;
  266.     aFileName.lpstrFilter = ExtFilter;
  267.     aFileName.lpstrCustomFilter = NULL; 
  268.     aFileName.nMaxCustFilter = 0L; 
  269.     aFileName.nFilterIndex = 0; 
  270.     aFileName.lpstrFile = inPathName; 
  271.     aFileName.nMaxFile = 255; 
  272.     aFileName.lpstrFileTitle = NULL;    
  273.     aFileName.nMaxFileTitle = 0; 
  274.     aFileName.lpstrInitialDir = NULL;  
  275.     aFileName.lpstrTitle = NULL;    
  276.     aFileName.Flags = OFN_EXPLORER + OFN_LONGNAMES + OFN_PATHMUSTEXIST; 
  277.     if( fOpen )
  278.         aFileName.Flags += OFN_FILEMUSTEXIST;
  279.     aFileName.nFileOffset = 0; 
  280.     aFileName.nFileExtension = 0; 
  281.     aFileName.lpstrDefExt = NULL; 
  282.     aFileName.lCustData = 0; 
  283.     aFileName.lpfnHook = NULL; 
  284.     aFileName.lpTemplateName = NULL; 
  285.     if (fOpen )
  286.         if (GetOpenFileName((LPOPENFILENAME)&aFileName))
  287.             aStatus = kQ3Success;
  288.         else
  289.             aStatus = kQ3Failure;
  290.     else //saving
  291.         if (GetSaveFileName((LPOPENFILENAME)&aFileName))
  292.             aStatus = kQ3Success;
  293.         else
  294.             aStatus = kQ3Failure;
  295.  
  296.     return aStatus;
  297. }
  298.  
  299. #if 0  // Use UnixPathStorage
  300. void    OpenModelFile(void)
  301. {
  302.     #undef A3Assert
  303.     #define    A3Assert(x)        if (!(x)) goto ExitOpenModelFile
  304.  
  305.     char                *pathName;
  306.     char                pathNameChars[255];
  307.     TQ3StorageObject    srcStorage = NULL;
  308.     TQ3FileObject        srcFileObject = NULL;
  309.     TQ3GroupObject        aGroup = NULL;
  310.     TQ3Object            anObject = NULL;
  311.     TQ3FileMode            srcFileMode;
  312.     TQ3GroupPosition    aPosition;
  313.     FILE                *aFile;
  314.     TQ3Status            aStatus;
  315.     int                    aResult;
  316.     RECT                aWinRect;
  317.     BOOL                aBoolResult;
  318.  
  319.     pathName = &(pathNameChars[0]);
  320.     if (BrowseForPathName(pathName, TRUE) != kQ3Success)
  321.         goto ExitOpenModelFile;
  322.     //aFile = fopen(pathName, "rb");
  323.     A3Assert((srcFileObject = Q3File_New()) != NULL);
  324.     A3Assert((srcStorage = Q3UnixPathStorage_New(pathName)) != NULL);
  325.     A3Assert((aStatus = Q3File_SetStorage(srcFileObject, srcStorage)) == kQ3Success);
  326.     A3Assert((aStatus = Q3File_OpenRead(srcFileObject, &srcFileMode)) == kQ3Success);
  327.     A3Assert((aGroup = Q3DisplayGroup_New()) != NULL);
  328.     while (Q3File_IsEndOfFile(srcFileObject) == kQ3False)
  329.     {
  330.         A3Assert((anObject = Q3File_ReadObject(srcFileObject)) != NULL);
  331.         A3Assert(Q3Error_Get(NULL) == kQ3ErrorNone);
  332.         if (Q3Object_IsDrawable(anObject) == kQ3True)
  333.             A3Assert((aPosition = Q3Group_AddObject(aGroup, anObject)) != NULL);
  334.         A3Assert(Q3Object_Dispose(anObject) == kQ3Success);
  335.         anObject = NULL;
  336.     }
  337.     A3Assert((Q3Object_Dispose(gDocument->fModel)) == kQ3Success);
  338.     gDocument->fModel = aGroup;
  339.     A3Assert((aStatus = Q3File_Close(srcFileObject)) == kQ3Success);
  340.     //aResult = fclose(aFile);
  341.     A3Assert((aStatus = Q3Object_Dispose(srcFileObject)) == kQ3Success);
  342.     A3Assert((aStatus = Q3Object_Dispose(srcStorage)) == kQ3Success);
  343.     gDocument->fControlStripVisible = kQ3True;
  344.     pvCamera_Fit(gDocument);
  345. /*    UpdateWindow(gDocument->fWindow); */
  346.     aBoolResult = GetClientRect(gDocument->fWindow, (LPRECT)&aWinRect);
  347.     aBoolResult = InvalidateRect(gDocument->fWindow, &aWinRect, FALSE);    
  348.  
  349. ExitOpenModelFile:
  350.     ;
  351. }
  352. #else // use UnixStorage
  353. void    OpenModelFile(void)
  354. {
  355.     #undef A3Assert
  356.     #define    A3Assert(x)        if (!(x)) goto ExitOpenModelFile
  357.  
  358.     char                *pathName;
  359.     char                pathNameChars[255];
  360.     TQ3StorageObject    srcStorage = NULL;
  361.     TQ3FileObject        srcFileObject = NULL;
  362.     TQ3GroupObject        aGroup = NULL;
  363.     TQ3Object            anObject = NULL;
  364.     TQ3FileMode            srcFileMode;
  365.     TQ3GroupPosition    aPosition;
  366.     FILE                *aFile;
  367.     TQ3Status            aStatus;
  368.     int                    aResult;
  369.     RECT                aWinRect;
  370.     BOOL                aBoolResult;
  371.  
  372.     pathName = &(pathNameChars[0]);
  373.     if (BrowseForPathName(pathName, TRUE) != kQ3Success)
  374.         goto ExitOpenModelFile;
  375.     aFile = fopen(pathName, "rb");
  376.     A3Assert((srcFileObject = Q3File_New()) != NULL);
  377.     A3Assert((srcStorage = Q3UnixStorage_New(aFile)) != NULL);
  378.     A3Assert((aStatus = Q3File_SetStorage(srcFileObject, srcStorage)) == kQ3Success);
  379.     A3Assert((aStatus = Q3File_OpenRead(srcFileObject, &srcFileMode)) == kQ3Success);
  380.     A3Assert((aGroup = Q3DisplayGroup_New()) != NULL);
  381.     while (Q3File_IsEndOfFile(srcFileObject) == kQ3False)
  382.     {
  383.         A3Assert((anObject = Q3File_ReadObject(srcFileObject)) != NULL);
  384.         A3Assert(Q3Error_Get(NULL) == kQ3ErrorNone);
  385.         if (Q3Object_IsDrawable(anObject) == kQ3True)
  386.             A3Assert((aPosition = Q3Group_AddObject(aGroup, anObject)) != NULL);
  387.         A3Assert(Q3Object_Dispose(anObject) == kQ3Success);
  388.         anObject = NULL;
  389.     }
  390.     A3Assert((Q3Object_Dispose(gDocument->fModel)) == kQ3Success);
  391.     gDocument->fModel = aGroup;
  392.     A3Assert((aStatus = Q3File_Close(srcFileObject)) == kQ3Success);
  393.     aResult = fclose(aFile);
  394.     A3Assert((aStatus = Q3Object_Dispose(srcFileObject)) == kQ3Success);
  395.     A3Assert((aStatus = Q3Object_Dispose(srcStorage)) == kQ3Success);
  396.     gDocument->fControlStripVisible = kQ3True;
  397.     pvCamera_Fit(gDocument);
  398. /*    UpdateWindow(gDocument->fWindow); */
  399.     aBoolResult = GetClientRect(gDocument->fWindow, (LPRECT)&aWinRect);
  400.     aBoolResult = InvalidateRect(gDocument->fWindow, &aWinRect, FALSE);    
  401.  
  402. ExitOpenModelFile:
  403.     ;
  404. }
  405. #endif //0 
  406.  
  407. void    SaveModelFile(void)
  408. {
  409.     #undef A3Assert
  410.     #define    A3Assert(x)        if (!(x)) goto ExitSaveModelFile
  411.  
  412.     char                *pathName;
  413.     char                pathNameChars[255];
  414.     TQ3FileObject        dstFileObject = NULL;
  415.     TQ3StorageObject    dstStorage = NULL;
  416.     TQ3FileMode            dstFileMode;
  417.     TQ3ViewObject        dstView;
  418.     TQ3Status            aStatus;
  419.     TQ3ViewStatus        aViewStatus;
  420.     FILE                *aFile;
  421.     int                    aResult;
  422.  
  423.     pathName = &(pathNameChars[0]);
  424.     if (BrowseForPathName(pathName, FALSE) != kQ3Success)
  425.         goto ExitSaveModelFile;
  426.     aFile = fopen(pathName, "wb"); 
  427.     A3Assert((dstFileObject = Q3File_New()) != NULL);
  428.     A3Assert((dstStorage = Q3UnixStorage_New(aFile)) != NULL);
  429.     A3Assert((aStatus = Q3File_SetStorage(dstFileObject, dstStorage)) == kQ3Success);
  430.     A3Assert((dstView = Q3View_New()) != NULL);
  431.     dstFileMode = kQ3FileModeNormal;
  432.     A3Assert((aStatus = Q3File_OpenWrite(dstFileObject, dstFileMode)) == kQ3Success);
  433.     A3Assert((aStatus = Q3View_StartWriting(dstView, dstFileObject)) == kQ3Success);
  434.     do
  435.     {
  436.         A3Assert((aStatus = Q3Object_Submit(gDocument->fModel, dstView)) == kQ3Success);
  437.         A3Assert((aViewStatus = Q3View_EndWriting(dstView)) != kQ3ViewStatusError);
  438.     } while (aViewStatus == kQ3ViewStatusRetraverse);
  439.     A3Assert((aStatus = Q3File_Close(dstFileObject)) == kQ3Success);
  440.     aResult = fclose(aFile);
  441.     A3Assert((aStatus = Q3Object_Dispose(dstFileObject)) == kQ3Success);
  442.     A3Assert((aStatus = Q3Object_Dispose(dstStorage)) == kQ3Success);
  443.  
  444. ExitSaveModelFile:
  445.     ;
  446. }
  447.  
  448.  
  449.  
  450. BOOL CenterWindow (HWND hwndChild, HWND hwndParent)
  451. {
  452.         RECT    rChild, rParent;
  453.         int     wChild, hChild, wParent, hParent;
  454.         int     wScreen, hScreen, xNew, yNew;
  455.         HDC     hdc;
  456.  
  457.         // Get the Height and Width of the child window
  458.         GetWindowRect (hwndChild, &rChild);
  459.         wChild = rChild.right - rChild.left;
  460.         hChild = rChild.bottom - rChild.top;
  461.  
  462.         // Get the Height and Width of the parent window
  463.         GetWindowRect (hwndParent, &rParent);
  464.         wParent = rParent.right - rParent.left;
  465.         hParent = rParent.bottom - rParent.top;
  466.  
  467.         // Get the display limits
  468.         hdc = GetDC (hwndChild);
  469.         wScreen = GetDeviceCaps (hdc, HORZRES);
  470.         hScreen = GetDeviceCaps (hdc, VERTRES);
  471.         ReleaseDC (hwndChild, hdc);
  472.  
  473.         // Calculate new X position, then adjust for screen
  474.         xNew = rParent.left + ((wParent - wChild) /2);
  475.         if (xNew < 0) {
  476.                 xNew = 0;
  477.         } else if ((xNew+wChild) > wScreen) {
  478.                 xNew = wScreen - wChild;
  479.         }
  480.  
  481.         // Calculate new Y position, then adjust for screen
  482.         yNew = rParent.top  + ((hParent - hChild) /2);
  483.         if (yNew < 0) {
  484.                 yNew = 0;
  485.         } else if ((yNew+hChild) > hScreen) {
  486.                 yNew = hScreen - hChild;
  487.         }
  488.  
  489.         // Set it, and return
  490.         return SetWindowPos (hwndChild, NULL,
  491.                 xNew, yNew, 0, 0, SWP_NOSIZE | SWP_NOZORDER);
  492. }
  493.  
  494.  
  495. // About box callback
  496. LRESULT CALLBACK About(
  497.                 HWND hDlg,           // window handle of the dialog box
  498.                 UINT message,        // type of message
  499.                 WPARAM uParam,       // message-specific information
  500.                 LPARAM lParam)
  501. {
  502.         static  HFONT hfontDlg;
  503.         LPSTR   lpVersion;
  504.         DWORD   dwVerInfoSize;
  505.         DWORD   dwVerHnd;
  506.         UINT    uVersionLen;
  507.         WORD    wRootLen;
  508.         BOOL    bRetCode;
  509.         int     i;
  510.         char    szFullPath[256];
  511.         char    szResult[256];
  512.         char    szGetName[256];
  513.  
  514.         switch (message) {
  515.                 case WM_INITDIALOG:  // message: initialize dialog box
  516.                         // Center the dialog over the application window
  517.                         CenterWindow (hDlg, GetWindow (hDlg, GW_OWNER));
  518.  
  519.                         // Get version information from the application
  520.                         GetModuleFileName (hInst, szFullPath, sizeof(szFullPath));
  521.                         dwVerInfoSize = GetFileVersionInfoSize(szFullPath, &dwVerHnd);
  522.                         if (dwVerInfoSize) {
  523.                                 // If we were able to get the information, process it:
  524.                                 LPSTR   lpstrVffInfo;
  525.                                 HANDLE  hMem;
  526.                                 hMem = GlobalAlloc(GMEM_MOVEABLE, dwVerInfoSize);
  527.                                 lpstrVffInfo  = GlobalLock(hMem);
  528.                                 GetFileVersionInfo(szFullPath, dwVerHnd, dwVerInfoSize, lpstrVffInfo);
  529.                                 lstrcpy(szGetName, "\\StringFileInfo\\040904e4\\");
  530.                                 wRootLen = lstrlen(szGetName);
  531.  
  532.                                 // Walk through the dialog items that we want to replace:
  533.                                 for (i = IDC_FILEDESCRIPTION; i <= IDC_LEGALTRADEMARKS; i++) {
  534.                                         GetDlgItemText(hDlg, i, szResult, sizeof(szResult));
  535.                                         szGetName[wRootLen] = (char)0;
  536.                                         lstrcat (szGetName, szResult);
  537.                                         uVersionLen   = 0;
  538.                                         lpVersion     = NULL;
  539.                                         bRetCode      =  VerQueryValue((LPVOID)lpstrVffInfo,
  540.                                                 (LPSTR)szGetName,
  541.                                                 (LPVOID)&lpVersion,
  542.                                                 (LPDWORD)&uVersionLen); // For MIPS strictness
  543.  
  544.                                         if ( bRetCode && uVersionLen && lpVersion) {
  545.                                                 // Replace dialog item text with version info
  546.                                                 lstrcpy(szResult, lpVersion);
  547.                                                 SetDlgItemText(hDlg, i, szResult);
  548.                                         }
  549.                                 }
  550.  
  551.                                 GlobalUnlock(hMem);
  552.                                 GlobalFree(hMem);
  553.                         } // if (dwVerInfoSize)
  554.                         return (TRUE);
  555.  
  556.                 case WM_COMMAND:                      // message: received a command
  557.                         if (LOWORD(uParam) == IDOK        // "OK" box selected?
  558.                         || LOWORD(uParam) == IDCANCEL) {  // System menu close command?
  559.                                 EndDialog(hDlg, TRUE);        // Exit the dialog
  560.                                 DeleteObject (hfontDlg);
  561.                                 return (TRUE);
  562.                         }
  563.                         break;
  564.         }
  565.         return (FALSE); // Didn't process the message
  566. }
  567.  
  568. //-------------------------------------------------------------------------------------------
  569. //
  570.  
  571. void InitDocumentData( DocumentPtr theDocument, HWND inWindow ) 
  572. {
  573.     RECT                aWinRect;
  574.     BOOL                aResult;
  575.  
  576.     theDocument->fWindow = inWindow;
  577.     aResult = GetClientRect(inWindow, (LPRECT)&aWinRect);
  578.     theDocument->fWidth = aWinRect.right - aWinRect.left;
  579.     theDocument->fHeight = aWinRect.bottom - aWinRect.top;
  580.  
  581.     // sets up the 3d data for the scene
  582.     // Create view for QuickDraw 3D
  583.     theDocument->fView = MyNewView( theDocument ) ;
  584.  
  585.     // the main display group
  586.     theDocument->fModel = MyNewModel() ;
  587.  
  588.     // the drawing styles:
  589.     theDocument->fInterpolation = Q3InterpolationStyle_New(kQ3InterpolationStyleVertex) ;
  590.     theDocument->fBackFacing = Q3BackfacingStyle_New(kQ3BackfacingStyleBoth ) ;
  591.     theDocument->fFillStyle = Q3FillStyle_New(kQ3FillStyleFilled ) ;
  592.     theDocument->fIllumination = Q3PhongIllumination_New();
  593.  
  594.     // set the rotation matrix the identity matrix
  595.     Q3Matrix4x4_SetIdentity(&theDocument->fRotation);
  596.  
  597.     theDocument->fControlStripVisible = kQ3False;
  598.     theDocument->fViewerMode = kA3BtnRotate;
  599. }
  600.  
  601. void DisposeDocumentData( DocumentPtr theDocument)
  602. {
  603.     Q3Object_Dispose(theDocument->fView) ;                // the view for the scene
  604.     Q3Object_Dispose(theDocument->fModel) ;                // object in the scene being modelled
  605.     Q3Object_Dispose(theDocument->fInterpolation) ;        // interpolation style used when rendering
  606.     Q3Object_Dispose(theDocument->fBackFacing) ;        // whether to draw shapes that face away from the camera
  607.     Q3Object_Dispose(theDocument->fFillStyle) ;            // whether drawn as solid filled object or decomposed to components
  608.     Q3Object_Dispose(theDocument->fIllumination) ;
  609. }
  610. //-----------------------------------------------------------------------------
  611. // 
  612.  
  613. TQ3Status DocumentDraw3DData( DocumentPtr theDocument )
  614. {
  615.     RECT            aWinRect;
  616.     BOOL            aResult;
  617.     HDC                hdc;
  618.  
  619.     aResult = GetClientRect(theDocument->fWindow, (LPRECT)&aWinRect);
  620.     hdc = GetDC(theDocument->fWindow);
  621.     Q3View_StartRendering(theDocument->fView );    
  622.     do {    
  623.         Q3Shader_Submit( theDocument->fIllumination, theDocument->fView );    
  624.         Q3Style_Submit( theDocument->fInterpolation, theDocument->fView );    
  625.         Q3Style_Submit( theDocument->fBackFacing, theDocument->fView );    
  626.         Q3Style_Submit( theDocument->fFillStyle, theDocument->fView );    
  627.         Q3MatrixTransform_Submit( &theDocument->fRotation, theDocument->fView );    
  628.         Q3DisplayGroup_Submit( theDocument->fModel, theDocument->fView );    
  629.     } while (Q3View_EndRendering(theDocument->fView) == kQ3ViewStatusRetraverse );    
  630.  
  631.     BitBlt(hdc, 0, 0, theDocument->fWidth, theDocument->fHeight,    
  632.             theDocument->fMemoryDC, 0, 0, SRCCOPY);                    
  633.     GdiFlush();    
  634.     ReleaseDC(theDocument->fWindow, hdc);                
  635.  
  636.     return kQ3Success ;
  637. }
  638.  
  639. TQ3Status DocumentNewWindowSize(DocumentPtr theDocument, unsigned long width, unsigned long height)
  640. {
  641.     BOOL        result;
  642.     TQ3Status    aStatus = kQ3Success;
  643.  
  644.     if (theDocument->fControlStripVisible == kQ3True)
  645.     {
  646.         theDocument->fWidth = width;
  647.         theDocument->fHeight = height;
  648.         result = DeleteObject(theDocument->fBitmap);
  649.         result = DeleteDC(theDocument->fMemoryDC);
  650.         Q3Object_Dispose(theDocument->fView);
  651.         theDocument->fView = MyNewView(theDocument);
  652.         pvCamera_Fit(gDocument);
  653.     }
  654.     return aStatus;
  655. }
  656.  
  657.